﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using ComponentSystem;
using Cysharp.Threading.Tasks;

namespace DataCenterSystem
{
    public partial class MemoryCacheBase_Entity : EntityCSharp, IMemoryCache
    {
        public ICacheEncoder Encoder => this.GetComponent<CacheEncoderBase_Com>();
        public ICacheDecoder Decoder => this.GetComponent<CacheDecoderBase_Com>();
        
        private IDictionary<string, byte[]> MemoryMap = new ConcurrentDictionary<string, byte[]>();
    }
    
    public partial class MemoryCacheBase_Entity
    {
        
        public virtual async UniTask<bool> AddOrUpdateCache(string key, byte[] data)
        {
            if (await ContainsKey(key))
            {
                if (await ContainsCache(key, data)) return true;//已经有一摸一样的了，就不换了
                MemoryMap[key] = data;
                return true;
            }
            else
            {
                return MemoryMap.TryAdd(key, data);
            }
        }
        
        public virtual async UniTask<MemoryCacheResult> GetCache(string key)
        {
            if(!await HasCache(key)) return new MemoryCacheResult(false, null);

            MemoryMap.TryGetValue(key, out var value);
            return new MemoryCacheResult(true, value);
        }

        public virtual async UniTask<bool> ContainsKey(string key)
        {
            if (MemoryMap.ContainsKey(key)) return true;
            return false;
        }

        public virtual async UniTask<bool> HasCache(string key)
        {
            if (!await ContainsKey(key)) return false;
            
            bool hasKey = MemoryMap.TryGetValue(key, out var value);
            if (hasKey && value != null && value.Length > 0)
            {
                return true;
            }

            return false;
        }

        public virtual async UniTask<bool> ContainsCache(string key, byte[] data)
        {
            if(!await HasCache(key)) return false;

            if (MemoryMap[key].SequenceEqual(data)) return true;
            else return false;
        }

        public virtual async UniTask<bool> Delete(string key)
        {
            if (!await ContainsKey(key)) return false;
            
            return MemoryMap.Remove(key);
        }
        
        public virtual async UniTask<bool> Clear()
        {
            try
            {
                MemoryMap.Clear();
                return true;
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogError($"MemoryCacheBase_Entity Clear() 清理缓存异常 e: {e.Message}");
                return false;
            }
        }

    }
}